#include "pch.h"
#include "droptarget.h"

HRESULT JOUI::DropTarget::QueryInterface(
    /* [in] */ REFIID riid,
    /* [iid_is][out] */ _COM_Outptr_ void __RPC_FAR *__RPC_FAR *ppvObject)
{
    return S_OK;
};

ULONG JOUI::DropTarget::AddRef(void)
{
    return S_OK;
};

ULONG JOUI::DropTarget::Release(void)
{
    return S_OK;
};

JOUI::DropTarget::DropTarget(UIWnd *pWnd)
{
    m_pWnd = pWnd;
};

HRESULT JOUI::DropTarget::DragEnter(
    /* [unique][in] */ __RPC__in_opt IDataObject *pDataObj,
    /* [in] */ DWORD grfKeyState,
    /* [in] */ POINTL pt,
    /* [out][in] */ __RPC__inout DWORD *pdwEffect)
{
    return S_OK;
};

HRESULT JOUI::DropTarget::DragOver(
    /* [in] */ DWORD grfKeyState,
    /* [in] */ POINTL pt,
    /* [out][in] */ __RPC__inout DWORD *pdwEffect)
{
    m_pWnd->wm_nchittest(MAKELONG(pt.x, pt.y));
    auto objHittest = m_pWnd->m_data.objHittest;
    if (objHittest)
    {
        if (((objHittest->StyleEx() & eos_ex_dragdrop) == eos_ex_dragdrop))
            return S_OK;
    }
    *pdwEffect = 0;
    return S_FALSE;
};

HRESULT JOUI::DropTarget::DragLeave(void)
{
    return S_OK;
};

HRESULT JOUI::DropTarget::Drop(
    /* [unique][in] */ __RPC__in_opt IDataObject *pDataObj,
    /* [in] */ DWORD grfKeyState,
    /* [in] */ POINTL pt,
    /* [out][in] */ __RPC__inout DWORD *pdwEffect)
{
    HWND hWnd = m_pWnd->GethWnd();
    m_pWnd->wm_nchittest(MAKELONG(pt.x, pt.y));
    auto objHittest = m_pWnd->m_data.objHittest;
    if (objHittest)
    {
        if (((objHittest->StyleEx() & eos_ex_dragdrop) == eos_ex_dragdrop))
        {
            info_dropinfo dropinfo{};
            dropinfo.pDataObject = pDataObj;
            dropinfo.grfKeyState = grfKeyState;
            dropinfo.x = pt.x;
            dropinfo.y = pt.y;
            DWORD retEffect = objHittest->baseproc(hWnd, WM_EX_DROP, 0, (LPARAM)&dropinfo);
            *pdwEffect = retEffect;
            if ((objHittest->StyleEx() & eos_ex_acceptfiles) == eos_ex_acceptfiles)
            {
                FORMATETC cFmt;
                cFmt.cfFormat = CF_HDROP;
                cFmt.ptd = 0;
                cFmt.dwAspect = DVASPECT_CONTENT;
                cFmt.lindex = -1;
                cFmt.tymed = TYMED_HGLOBAL;
                if (pDataObj->QueryGetData(&cFmt) == 0)
                {
                    STGMEDIUM stgMedium = {0};
                    if (pDataObj->GetData(&cFmt, &stgMedium) == 0)
                    {
                        LPVOID hDrop = stgMedium.hBitmap;
                        retEffect = objHittest->baseproc(hWnd, WM_DROPFILES, 0, (size_t)hDrop);
                        *pdwEffect = retEffect;
                        if (stgMedium.hMetaFilePict == 0)
                        {
                            GlobalFree(hDrop);
                        }
                    }
                    ReleaseStgMedium(&stgMedium);
                }
            }
        }
    }
    return S_OK;
};